<?php


namespace App\Controllers;


use App\Models\BotModel;
use CodeIgniter\API\ResponseTrait;
use CodeIgniter\Controller;

class Bot extends Controller
{

    use ResponseTrait;

    public function __construct()
    {
        helper('bot');
    }

    /**
     * @title 返回可使用端口
     * @return \json
     */
    public function portCheck()
    {
        $ports = check_surplus_port();
        $port = $ports[array_rand($ports)];
        $res_data = [
            'data' => ['ports' => $ports, 'port' => $port],
            'status' => 200,
        ];
        return $this->respondCreated($res_data);
    }


    /**
     * @title 端口注册机器（文件）
     * @param domain :string :域名
     * @param host :string :ip
     * @param account :string :账号
     * @param device :string :设备名
     * @return \json
     */
    public function openBot()
    {
        $validation = \Config\Services::validation();
        $params = $this->request->getPost();
        if (!$validation->run($params, 'domain_host_account_device')) {
            return $this->failValidationErrors(implode('\\', array_values($validation->getErrors())));
        }
        $BotModel = new BotModel();
        $ports = check_surplus_port();
        $port = $ports[array_rand($ports)];

        $ins_data['domain'] = $params['domain'];
        $ins_data['host'] = $params['host'];
        $ins_data['port'] = $port;
        $ins_data['account'] = $params['account'];
        $ins_data['device'] = strtoupper($params['device']);;
        $ins_data['create_time'] = time();
        $ins_data['secret_str'] = rand_str();

        $BotModel->db->transStatus();
        try {
            $res = $BotModel->insert($ins_data);
            if (is_integer($res) && !empty($res)) ready_device($ins_data['port'], $ins_data['device']);
            $BotModel->db->transCommit();
        } catch (\Exception $p) {
            $BotModel->db->transRollback();
            $msg = str_replace(masking_dir(), masking_replace(), $p->getMessage());
            return $this->fail($msg, 400);
        }
        $res_data = [
            'data' => [
                'port' => $ins_data['port'],
                'secret_str' => $ins_data['secret_str'],
            ],
            'status' => 200,
        ];
        return $this->respondCreated($res_data);
    }


    /**
     * @title 端口删除机器（文件、进程）
     * @param port :int :端口
     * @return \json
     */
    public function quitBot()
    {
        $BotModel = new BotModel();
        $validation = \Config\Services::validation();
        $params = $this->request->getPost();
        if (!$validation->run($params, 'port')) {
            return $this->failValidationErrors(implode('\\', array_values($validation->getErrors())));
        }
        $BotModel->db->transStatus();
        try {
            del_device($params['port']);
            $BotModel->where(['port' => $params['port']])->delete();
            $BotModel->db->transCommit();
        } catch (\Exception $p) {
            $BotModel->db->transRollback();
            $msg = str_replace(masking_dir(), masking_replace(), $p->getMessage());
            return $this->fail($msg, 400);
        }
        $res_data = [
            'data' => ['port' => $params['port']],
            'status' => 200,
        ];
        return $this->respondDeleted($res_data);
    }


    /**
     * @title 根据端口进程机器账号登录（进程）
     * @param port :int :端口
     * @return \json
     */
    public function loginBot()
    {
        $validation = \Config\Services::validation();
        $params = $this->request->getGet();
        if (!$validation->run($params, 'port')) {
            return $this->failValidationErrors(implode('\\', array_values($validation->getErrors())));
        }
        try {
            init_device($params['port']);
        } catch (\Exception $p) {
            $msg = str_replace(masking_dir(), masking_replace(), $p->getMessage());
            return $this->fail($msg, 400);
        }
        try {
            $base64_img = device_qrcode($params['port']);
        } catch (\Exception $p) {
            return $this->fail('qr code error', 400);
        }
        $res_data = [
            'data' => ['qrcode' => $base64_img],
            'status' => 200,
        ];
        return $this->respondCreated($res_data);
    }

    /**
     * @title 根据端口进程机器账号退出（进程）
     * @param port :int :端口
     * @return mixed
     */
    public function quitBotAccount()
    {
        $BotModel = new BotModel();
        $validation = \Config\Services::validation();
        $params = $this->request->getPost();
        if (!$validation->run($params, 'port')) {
            return $this->failValidationErrors(implode('\\', array_values($validation->getErrors())));
        }
        $BotModel->db->transStatus();
        try {
            device_quit_account($params['port']);
            $BotModel->where(['port' => $params['port']])->set(['status'=>'offline'])->update();
            $BotModel->db->transCommit();
        } catch (\Exception $p) {
            $BotModel->db->transRollback();
            $msg = str_replace(masking_dir(), masking_replace(), $p->getMessage());
            return $this->fail($msg, 400);
        }
        $res_data = [
            'data' => ['port' => $params['port']],
            'status' => 200,
        ];
        return $this->respondCreated($res_data);

    }


    /**
     * @title 根据端口进程机器账号检测在线情况
     * @param port :int :端口
     * @return \json
     */
    public function checkBot()
    {
        $validation = \Config\Services::validation();
        $params = $this->request->getGet();
        if (!$validation->run($params, 'port')) {
            return $this->failValidationErrors(implode('\\', array_values($validation->getErrors())));
        }
        try {
            $state = get_status($params);
        } catch (\Exception $p) {
            $msg = str_replace(masking_dir(), masking_replace(), $p->getMessage());
            return $this->fail($msg, 400);
        }
        $states = json_decode($state, true);
        if ($states['data']['online'] === true) {
            $res_data = [
                'data' => ['state'=>'online'],
                'status' => 200,
            ];
            return $this->respondCreated($res_data);
        }
        $msg = [];
        return $this->fail($msg, 400);
    }


}